//////////////////////////////////////////////////////////////////////////

#ifndef _DATABASE_H_
#include "database.h"
#endif

//////////////////////////////////////////////////////////////////////////

#ifndef _PATIENT_H_
#include "patient.h"
#endif

#ifndef _QUERIES_H_
#include "queries.h"
#endif

#include <string>
#include <iostream>

//////////////////////////////////////////////////////////////////////////


Database::Database()
{
    m_DB = QSqlDatabase::addDatabase("QSQLITE");
    m_DB.setDatabaseName("base.db");
    m_DB.open();
    /*if ( m_DB.open() )
    {
        m_Model = new QSqlTableModel(NULL, m_DB);
        m_Model->setTable("PATIENTS");
        m_Model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        m_Model->select();
    }*/
}


//////////////////////////////////////////////////////////////////////////


Database::~Database()
{
    m_DB.close();
}


//////////////////////////////////////////////////////////////////////////


void Database::AddPatient( const Patient& _patient )
{
    static QSqlQuery query(m_DB);
    static bool prepared = false;
    if (!prepared)
    {
        query.prepare(QUERY_INSERT_PATIENT);
        prepared = true;
    }

    query.addBindValue(_patient.GetHistoryNumber());
    query.addBindValue(_patient.GetSurname());
    query.addBindValue(_patient.GetName());
    query.addBindValue(_patient.GetSecondName());
    query.addBindValue(_patient.GetBirthDate());
    query.addBindValue(_patient.GetSex());
    query.addBindValue(_patient.GetDiagnosis());
    query.addBindValue(_patient.GetNotes());
    query.exec();

}


//////////////////////////////////////////////////////////////////////////


void Database::DeletePatient( const Patient& _patient )
{
    static QSqlQuery query(m_DB);
    static bool prepared = false;
    if (!prepared)
    {
        query.prepare(QUERY_DELETE_PATIENT_BY_HISTORY);
        prepared = true;
    }

    query.addBindValue(_patient.GetHistoryNumber());
    query.exec();
}


//////////////////////////////////////////////////////////////////////////


void Database::UpdatePatient( const Patient& _patient )
{
    static QSqlQuery query(m_DB);
    static bool prepared = false;
    if (!prepared)
    {
        query.prepare(QUERY_UPADTE_PATIENT);
        prepared = true;
    }
    
    query.addBindValue(_patient.GetSurname());
    query.addBindValue(_patient.GetName());
    query.addBindValue(_patient.GetSecondName());
    query.addBindValue(_patient.GetBirthDate());
    query.addBindValue(_patient.GetSex());
    query.addBindValue(_patient.GetDiagnosis());
    query.addBindValue(_patient.GetNotes());
    query.addBindValue(_patient.GetHistoryNumber());

    query.exec();
}


//////////////////////////////////////////////////////////////////////////


void Database::SaveCurrentResearch( const Patient& _patient )
{
    static QSqlQuery query(m_DB);
    static bool prepared = false;
    if (!prepared)
    {
        query.prepare(QUERY_SAVE_RESEARCH);
        prepared = true;
    }

    const Research* research = _patient.GetCurrentResearch();
    if (!research)
        return;

    const ResultsTable& results = research->GetResultsTable();

    query.addBindValue( _patient.GetHistoryNumber() );
    query.addBindValue( research->GetDate() );
    query.addBindValue( results.m_StepTime );
    query.addBindValue( results.m_RythmCoefficient );
    query.addBindValue( results.m_RightHeelDown );
    query.addBindValue( results.m_RightToeDown );
    query.addBindValue( results.m_RightFootDown );
    query.addBindValue( results.m_RightFootUp );
    query.addBindValue( results.m_LeftHeelDown );
    query.addBindValue( results.m_LeftToeDown );
    query.addBindValue( results.m_LeftFootDown );
    query.addBindValue( results.m_LeftFootUp );
    query.addBindValue( results.m_DoubleSeatPhase );

    query.exec();
}


//////////////////////////////////////////////////////////////////////////


void Database::FetchPatients(std::vector<Patient>& _patients, size_t _history) const
{
    static QSqlQuery query(m_DB);
    static bool prepared = false;
    if (!prepared)
    {
        query.prepare(QUERY_SELECT_PATIENT_BY_HISTORY);
        prepared = true;
    }

    query.addBindValue(_history);
    IteratePatientsTable(query, _patients);
}


//////////////////////////////////////////////////////////////////////////


void Database::FetchPatients(std::vector<Patient>& _patients, const QString& _surname) const
{
    static QSqlQuery query(m_DB);
    static bool prepared = false;
    if (!prepared)
    {
        query.prepare(QUERY_SELECT_PATIENT_BY_SURNAME);
        prepared = true;
    }

    query.addBindValue(_surname);
    IteratePatientsTable(query, _patients);

}


//////////////////////////////////////////////////////////////////////////


void Database::FetchPatientResearches( Patient& _patient ) const
{
    static QSqlQuery query(m_DB);
    static bool prepared = false;
    if (!prepared)
    {
        query.prepare(QUERY_SELECT_RESEARCHES_BY_HISTORY);
        prepared = true;
    }

    _patient.ClearResearches();

    query.addBindValue( _patient.GetHistoryNumber() );
    query.exec();

    while ( query.next() )
    {
        ResultsTable resTable;

        QString date = query.value(1).toString();
        resTable.m_StepTime = query.value(2).toDouble();
        resTable.m_RythmCoefficient = query.value(3).toDouble();
        resTable.m_RightHeelDown = query.value(4).toDouble();
        resTable.m_RightToeDown = query.value(5).toDouble();
        resTable.m_RightFootDown = query.value(6).toDouble();
        resTable.m_RightFootUp = query.value(7).toDouble();
        resTable.m_LeftHeelDown = query.value(8).toDouble();
        resTable.m_LeftToeDown = query.value(9).toDouble();
        resTable.m_LeftFootDown = query.value(10).toDouble();
        resTable.m_LeftFootUp = query.value(11).toDouble();
        resTable.m_DoubleSeatPhase = query.value(12).toDouble();

        Research research(date, resTable);
        _patient.AddLoadedResearch(research);
    }
}


//////////////////////////////////////////////////////////////////////////


void Database::IteratePatientsTable( QSqlQuery &query, std::vector<Patient> &_patients ) const
{
    _patients.clear();

    query.exec();

    while (query.next())
    {
        size_t history = query.value(0).toUInt();
        QString surname = query.value(1).toString();
        QString name = query.value(2).toString();
        QString secondName = query.value(3).toString();
        QString birthDate = query.value(4).toString();
        Patient::Sex sex = (Patient::Sex)query.value(5).toBool();
        QString diagnosis = query.value(6).toString();
        QString notes = query.value(7).toString();
        Patient patient(history, surname, name, secondName, birthDate, sex, diagnosis, notes );

        _patients.push_back(patient);
    }
}


//////////////////////////////////////////////////////////////////////////

